package ar.edu.itba.it.pdc.httpParser.models;

import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.List;
import java.util.Queue;

import ar.edu.itba.it.pdc.httpParser.interfaces.Model;
import ar.edu.itba.it.pdc.nio.ByteBufferPool;
import ar.edu.itba.it.pdc.nio.MemoryAllocationLimitHited;

public class HttpRequestLine implements Model{
	private Method method;

	private List<Token> resource;

	private HttpVersion version = null;
	
	ByteBuffer byteBuffer;
	
	public void setMethod(Method method) {
		this.method = method;
	}

	public void setResource(List<Token> resource) {
		this.resource = resource;
	}

	public void setVersion(HttpVersion version) {
		this.version = version;
	}

	private void add(Queue<ByteBuffer> queue, byte b) throws MemoryAllocationLimitHited {
		byteBuffer.put(b);
		if (byteBuffer.remaining() == 0) {
			byteBuffer.flip();
			queue.add(byteBuffer);
			byteBuffer = ByteBufferPool.getInstance().getByteBuffer();
		}
	}

	public void appendByteBuffers(Queue<ByteBuffer> queue) throws MemoryAllocationLimitHited {
		if(byteBuffer == null)
			byteBuffer = ByteBufferPool.getInstance().getByteBuffer();

		for (byte b : method.toString().getBytes()) {
			add(queue, b);
		}

		add(queue, (byte)' ');

		for (Token token : resource) {
			for (byte b : token.getName()) {
				add(queue, b);
			}
		}
		
		add(queue, (byte) ' ');

		add(queue, (byte) 'H');
		add(queue, (byte) 'T');
		add(queue, (byte) 'T');
		add(queue, (byte) 'P');
		add(queue, (byte) '/');

		for (byte b : version.toString().getBytes()) {
			add(queue, b);
		}

		add(queue, (byte) '\r');
		add(queue, (byte) '\n');

		if (byteBuffer.position() != 0) {
			byteBuffer.flip();
			queue.add(byteBuffer);
			byteBuffer =  null;
		}

	}

	public HttpVersion getVersion() {
		return version;
	}
	
	public String getResource() {
		String ans = "";
		for (Token token : resource) {
			ans += token.toString();
		}
		return ans;
	}

	public void removeHostFromSource() {
		if(resource.get(0).isType(TokenType.DIVIDE)){
			return;
		}
		
		int divCount = 0;
		Iterator<Token> it = resource.iterator();
		for(Token token = it.next(); it.hasNext(); token = it.next()){
			
			if(token.isType(TokenType.DIVIDE)){
				divCount++;
				if(divCount == 3){
					return;
				}
			}
			it.remove();
		}
		
	}
	
	public Method getMethod() {
		return method;
	}
}
